package com.justnow.offer.times02;

import org.omg.PortableServer.THREAD_POLICY_ID;

/**
 * @author justnow
 * Created on 2020-10-06
 * Description
 * 有序打印ABCABC。。。。。。。
 */
public class Demo02 {

    private static boolean flagA = true;
    private static boolean flagB = false;
    private static boolean flagC = false;
    private static Object o = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (o) {
                for (int i = 0; i < 10; ) {
                    // flagA为true，表明此时应该执行的是A线程。
                    if (flagA) {
                        System.out.print(Thread.currentThread().getName());
                        // 下一个轮到B打印，所以把startB置为true，其他为false
                        flagA = false;
                        flagB = true;
                        flagC = false;
                        // 唤醒其他处于等待状态的线程
                        o.notifyAll();
                        // 只有打印了，才让i加1
                        i++;
                    } else {
                        // 如果flagA不为true，表示此时需要执行其他的内容，所以直接将
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, "A").start();

        new Thread(() -> {
            synchronized (o) {
                for (int i = 0; i < 10;) {
                    if (flagB) {
                        System.out.print(Thread.currentThread().getName());
                        flagA = false;
                        flagB = false;
                        flagC = true;
                        //线程B执行了notifyAll方法后，并没有理解释放锁，
                        //而是继续执行后面的内容，再次循环的时候因为flagB为false，所以直接进入wait状态
                        o.notifyAll();
                        i++;
                    } else {
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }
        }, "B").start();

        new Thread(() -> {
            synchronized (o) {
                for (int i = 0; i < 10;) {
                    if (flagC) {
                        System.out.print(Thread.currentThread().getName());
                        flagA = true;
                        flagB = false;
                        flagC = false;
                        o.notifyAll();
                        i++;
                    } else {
                        try {
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }, "C").start();
    }
}
